﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EZ.Storage;

namespace TestProject2
{
	/// <summary>
	/// Summary description for UnitTest1
	/// </summary>
	[TestClass]
	public class UnitTest1
	{
		public UnitTest1()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }
		//
		// Use TestInitialize to run code before running each test 
		// [TestInitialize()]
		// public void MyTestInitialize() { }
		//
		// Use TestCleanup to run code after each test has run
		// [TestCleanup()]
		// public void MyTestCleanup() { }
		//
		#endregion

		[TestMethod]
		public void TestMethod1()
		{
			using ( RedisConnection redis = new RedisConnection( new Uri( "tcp://localhost:6379" ) ) )
			{
				redis.Open();

				// Get/Set
				redis.Keys.Set( "valor1", "1" );
				Assert.AreEqual( "1", redis.Keys.Get( "valor1" ) );

				// SETEX
				TimeSpan timeout = TimeSpan.FromSeconds( 5 );
				redis.Keys.Set( "v2", "2", timeout );
				Assert.AreEqual( "2", redis.Keys.Get( "v2" ) );
				System.Threading.Thread.Sleep( timeout.Add( TimeSpan.FromSeconds( 5 ) ) );
				Assert.IsNull( redis.Keys.Get( "v2" ) );

				// DBSIZE
				Assert.IsTrue( redis.Server.DbSize() > 0L );

				// FLUSHALL
				redis.Server.FlushAll();
				Assert.AreEqual( 0L, redis.Server.DbSize() );

				// SETNX
				Assert.IsTrue( redis.Keys.SetIfNotExists( "k1", "1" ) );
				Assert.IsFalse( redis.Keys.SetIfNotExists( "k1", "2" ) );
				Assert.AreEqual( "1", redis.Keys.Get( "k1" ) );

				// DELETE / EXISTS
				redis.Keys.Set( "k1", "1" );
				Assert.IsTrue( redis.Keys.Exists( "k1" ) );
				Assert.AreEqual( 1, redis.Keys.Delete( "k1" ) );
				Assert.IsFalse( redis.Keys.Exists( "k1" ) );

				// FindKeys
				redis.Server.FlushAll();
				redis.Keys.Set( "k1", "1" );
				redis.Keys.Set( "k2", "2" );
				redis.Keys.Set( "kb1", "3" );
				redis.Keys.Set( "kb2", "4" );
				var keysFound = redis.Keys.FindKeys( "kb*" ).ToList();
				CollectionAssert.AreEquivalent( new string[] { "kb1", "kb2" }, keysFound );
				
				// List
				var list = redis.Lists( "l1" );
				int added = list.Add( "v1", "v2", "v3", "v4", "v5", "v6", "v7", ( string )null, String.Empty, "v10" );
				Assert.AreEqual( 10, added );
				Assert.AreEqual( 10, list.Length );

				// RPUSH
				int newLen = list.Add( "v11" );
				Assert.AreEqual( 11, newLen );
				Assert.AreEqual( 11, list.Length );

				// Range
				var range = list.Range( 1, 3 ).ToList();
				CollectionAssert.AreEqual( Vector( "v2", "v3", "v4" ), range );

				Assert.AreEqual( "v1", list.ElementAt( 0 ) );
				Assert.IsNull( list.ElementAt( 7 ) );
				Assert.AreEqual( String.Empty, list.ElementAt( 8 ) );

				var first= list.RemoveFirst();
				Assert.AreEqual( "v1", first );

				var last = list.RemoveLast();
				Assert.AreEqual( "v11", last );
				Assert.AreEqual( 9, list.Length );

				list.Zip( 0, 5 );
				CollectionAssert.AreEqual( Vector( "v2", "v3", "v4", "v5", "v6" ), list.ToList() );

				// INC/DEC
				redis.Keys.Set( "n1", "2" );
				Assert.AreEqual( 3, redis.Keys.Increment( "n1" ) );
				Assert.AreEqual( 6, redis.Keys.Increment( "n1", 3 ) );
				Assert.AreEqual( "6", redis.Keys.Get( "n1" ) );

				redis.Keys.Set( "n2", "10" );
				Assert.AreEqual( 9, redis.Keys.Decrement( "n2" ) );
				Assert.AreEqual( 6, redis.Keys.Decrement( "n2", 3 ) );
				Assert.AreEqual( "6", redis.Keys.Get( "n2" ) );

				redis.Close();
			}
		}

		public string[] Vector( params string[] values )
		{
			return values;
		}
	}
}
